package cross;

import individuals.Individual;

import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;

public class MultipleCross implements Cross {
	
	private int n = 3;
	
	public MultipleCross(int n) {
		this.n=n;
		if(n>64 || n<1)
			throw new RuntimeException("La cantidad maxima de cortes del MultipleCross debe ser menor a 65 y mayor a 0");
	}
	
	/* (non-Javadoc)
	 * @see cross.Cross#Apply(individuals.Individual, individuals.Individual)
	 */
	@Override
	public List<Individual> Apply(Individual father, Individual mother) {
		List<Individual> list = new ArrayList<Individual>();
		TreeSet<Integer> cuts = new TreeSet<Integer>();
		
		long mask = 0;
		
		while(cuts.size()!=n) {
			cuts.add((int) Math.floor(Cross.ranGen.nextDouble()*63)); //no incluyo el ultimo corte
		}
		
		//cuts.add(63); 	//agrego la ultima posicion del double para que
						//pueda terminar la mascara (por si no toco como corte)
		
		int last = 0;
		int curr;
		int bit = 1;
		while(cuts.size() != 0) {
			curr = cuts.first();
			for(int j = 0; j<curr-last; j++) {
				mask<<=1;
				mask+=bit;
			}
			cuts.remove(curr);
			bit = (bit==0)? 1 : 0;
			last=curr;
		}
		System.out.println(mask);
		long mask1 = mask;
		long mask2 = mask;
		
		mask1 &= Double.doubleToRawLongBits(father.getGen());
		mask2 &= Double.doubleToRawLongBits(mother.getGen());
		
		mask = ~mask;
		Double son1 = Double.longBitsToDouble((Double.doubleToRawLongBits(father.getGen())&mask)|mask2);
		Double son2 = Double.longBitsToDouble((Double.doubleToRawLongBits(mother.getGen())&mask)|mask1);
		list.add(new Individual(son1));
		list.add(new Individual(son2));
		
		return list;
	}
}
